
using System;
using System.Data;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

using Abp.UI;
using Abp.AutoMapper;
using Abp.Extensions;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Application.Services.Dto;
using Abp.Linq.Extensions;
 
using JYJ.AiYard.StationManagement.TvDigitalPay.Dtos;
using JYJ.AiYard.StationManagement.TvDigitalPay.DomainService;
using JYJ.AiYard.StationManagement.TvDigitalPay.Authorization;
using JYJ.AiYard.StationManagement.YardReport;
using JYJ.AiYard.StationManagement.YardCommonHald;
using JYJ.AiYard.Database;
using Microsoft.AspNetCore.Http;
using JYJ.AiYard.StationManagement.Exporting;
using Microsoft.AspNetCore.Hosting;
using System.IO;
using AiYard.Common;
using Newtonsoft.Json;

namespace JYJ.AiYard.StationManagement.TvDigitalPay
{
	/// <summary>
	/// TvDigitalPay应用层服务的接口实现方法  
	///</summary>
	[AbpAuthorize]
	public class TvDigitalPayAppService : AiYardAppServiceBase, ITvDigitalPayAppService
	{
		private readonly IAiYardDbTableIssuedCard _aiYardDbTableIssuedCard;

		private readonly IRepository<TvDigitalPay, long> _entityRepository;

		private readonly ITvDigitalPayManager _entityManager;

		private readonly IListExcelExporter _listExcelExporter;

		private readonly IHostingEnvironment _hostingEnvironment;

		private readonly IHttpContextAccessor _httpContext;

		private readonly IHttpService _httpService;
		/// <summary>
		/// 构造函数 
		///</summary>
		public TvDigitalPayAppService(
		IRepository<TvDigitalPay, long> entityRepository,
		IAiYardDbTableIssuedCard aiYardDbTableIssuedCard,
		IListExcelExporter listExcelExporter,
		IHostingEnvironment hostingEnvironment,
		ITvDigitalPayManager entityManager,
		IHttpContextAccessor httpContext,
		IHttpService httpService
		)
		{
			_entityRepository = entityRepository;
			_entityManager = entityManager;
			_aiYardDbTableIssuedCard = aiYardDbTableIssuedCard;
			_listExcelExporter = listExcelExporter;
			_hostingEnvironment = hostingEnvironment;
			_httpContext = httpContext;
			_httpService = httpService;
		}


		/// <summary>
		/// 获取TvDigitalPay的分页列表信息
		///</summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[AbpAuthorize(TvDigitalPayPermissions.Query)]
		public async Task<PagedResultDto<tVDIGITALPAYMAIN>> GetPaged(GetTvDigitalPaysInput input)
		{
			List<long> StationList = new List<long>();
			tbQFilterText filterText = input.FilterText.ToObject<tbQFilterText>();
			if (filterText.StationId == null || filterText.StationId <= 0)
			{
				StationList = GetCurrenUserOrganizationAndChildrenUnit();
			}
			else
			{
				StationList.Add((long)filterText.StationId);
			}
			var qStr = filterText.FilterText.ToString().ToObject<queryfilterText>();
			DateTime bTime = (qStr.bTime == "" ? Convert.ToDateTime("1900-01-01") : Convert.ToDateTime(qStr.bTime));
			DateTime eTime = (qStr.eTime == "" ? Convert.ToDateTime("2900-01-01") : Convert.ToDateTime(qStr.eTime));
			var query = _aiYardDbTableIssuedCard.GetDIGITALPAY(StationList, bTime, eTime, qStr.Checked == 1).AsQueryable();

			var count = query.Count();
			if (input.Sorting == "Id")
			{
				query = query.OrderByDescending(o => (o.UpTime));
			}
			else
			{
				query = query.OrderBy(input.Sorting);
			}
			query = query.PageBy(input);


			var entityList = query.ToList();
			var entityListDtos = entityList.MapTo<List<tVDIGITALPAYMAIN>>();
			return new PagedResultDto<tVDIGITALPAYMAIN>(count, entityListDtos);
		}


		/// <summary>
		/// 通过指定id获取TvDigitalPayListDto信息
		/// </summary>
		[AbpAuthorize(TvDigitalPayPermissions.Query)]
		public async Task<TvDigitalPayListDto> GetById(EntityDto<long> input)
		{
			var entity = await _entityRepository.GetAsync(input.Id);

			return entity.MapTo<TvDigitalPayListDto>();
		}

		[AbpAuthorize(TvDigitalPayPermissions.Query)]
		public async Task<List<TvDigitalPayDto>> GetByBillNo(long stationId, string billNo)
		{
			return await _aiYardDbTableIssuedCard.GetBillInfo(stationId, billNo, false);
		}
		/// <summary>
		/// 获取编辑 TvDigitalPay
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[AbpAuthorize(TvDigitalPayPermissions.Create, TvDigitalPayPermissions.Edit)]
		public async Task<GetTvDigitalPayForEditOutput> GetForEdit(NullableIdDto<long> input)
		{
			var output = new GetTvDigitalPayForEditOutput();
			TvDigitalPayEditDto editDto;

			if (input.Id.HasValue)
			{
				long id = 0;
				if (input.Id.Value != null)
				{
					id = Convert.ToInt64(input.Id.Value);
				}
				var entity = await _entityRepository.GetAsync(id);
				editDto = entity.MapTo<TvDigitalPayEditDto>();
			}
			else
			{
				editDto = new TvDigitalPayEditDto();
			}

			output.TvDigitalPay = editDto;
			return output;
		}


		/// <summary>
		/// 添加或者修改TvDigitalPay的公共方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[AbpAuthorize(TvDigitalPayPermissions.Create, TvDigitalPayPermissions.Edit)]
		public async Task CreateOrUpdate(CreateOrUpdateTvDigitalPayInput input)
		{
			if (input.TvDigitalPay.Station_Id <= 0)
			{
				throw new UserFriendlyException("请选择确定的场所名称");
			}
			if (input.TvDigitalPay.Id.HasValue)
			{
				await Update(input.TvDigitalPay);
			}
			else
			{
				await Create(input.TvDigitalPay);
			}
		}


		/// <summary>
		/// 新增TvDigitalPay
		/// </summary>
		[AbpAuthorize(TvDigitalPayPermissions.Create)]
		protected virtual async Task<TvDigitalPayEditDto> Create(TvDigitalPayEditDto input)
		{

			//判断相同的客户端是否只存在一个
			var query = _entityRepository.GetAll()
				.Where(o => o.Station_Id == input.Station_Id);
			if (query.Count() > 0)
			{
				throw new UserFriendlyException("存在相同场所参数设置");
			}
			var entity = input.MapTo<TvDigitalPay>();


			entity = await _entityRepository.InsertAsync(entity);
			return entity.MapTo<TvDigitalPayEditDto>();
		}

		/// <summary>
		/// 编辑TvDigitalPay
		/// </summary>
		[AbpAuthorize(TvDigitalPayPermissions.Edit)]
		protected virtual async Task Update(TvDigitalPayEditDto input)
		{
			//判断相同的客户端是否只存在一个
			var query = _entityRepository.GetAll()
				.Where(o => o.Station_Id == input.Station_Id && o.Id != input.Id);
			if (query.Count() > 0)
			{
				throw new UserFriendlyException("存在相同场所参数设置");
			}

			var entity = await _entityRepository.GetAsync(input.Id.Value);
			input.MapTo(entity);
			await _entityRepository.UpdateAsync(entity);
		}



		/// <summary>
		/// 删除TvDigitalPay信息的方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[AbpAuthorize(TvDigitalPayPermissions.Delete)]
		public async Task Delete(EntityDto<long> input)
		{
			//TODO:删除前的逻辑判断，是否允许删除
			var entity = await _entityRepository.GetAsync(input.Id);
			if (entity != null && entity.CheckStatus == null)
			{
				List<tVDIGITALPAYIds> ids = _aiYardDbTableIssuedCard.GetDIGITALPAY(entity.Station_Id, entity.BillNo);
				foreach (tVDIGITALPAYIds id in ids)
				{
					await _entityRepository.DeleteAsync(id.Id);
				}
			}
		}


		/// <summary>
		/// 删除TvDigitalPay信息的方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		[AbpAuthorize(TvDigitalPayPermissions.Delete)]
		public async Task Delete2(EntityDto<long> input)
		{
			//TODO:删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(input.Id);
		}


		/// <summary>
		/// 批量删除TvDigitalPay的方法
		/// </summary>
		[AbpAuthorize(TvDigitalPayPermissions.BatchDelete)]
		public async Task BatchDelete(List<long> input)
		{
			// TODO:批量删除前的逻辑判断，是否允许删除
			foreach (long id in input)
			{
				EntityDto<long> dto = new EntityDto<long>();
				dto.Id = id;
				await Delete2(dto);
			}
		}

		/// <summary>
		/// 获取单号
		/// </summary>
		/// <param name="stationId"></param>
		/// <returns></returns>
		public async Task<string> GetBillNo(long stationId)
		{
			return _aiYardDbTableIssuedCard.GetBillNo(stationId);
		}


		/// <summary>
		/// 拥有导入权限
		/// </summary>
		/// <returns></returns>
		public async Task<userInfors> canUpload()
		{
			userInfors user = new userInfors()
			{
				can = false,
				email = "",
				isSync = 1,
				phone = ""
			};
			int opUserId = Convert.ToInt32(AbpSession.UserId);
			int canUp = _aiYardDbTableIssuedCard.getAudUserType(opUserId);
			if (canUp == 1 || canUp == 3) {
				var user2 = await UserManager.FindByIdAsync(opUserId.ToString());
				int issync = _aiYardDbTableIssuedCard.getAudPasswordType(opUserId);
				return new userInfors()
				{
					can = true,
					email = user2.EmailAddress,
					isSync = issync,
					phone = user2.PhoneNumber
				}; ;
			}
			return user;
		}

		/// <summary>
		/// 拥有审核权限
		/// </summary>
		/// <returns></returns>
		public async Task<userInfors> canCheck()
		{
			userInfors user = new userInfors()
			{
				can = false,
				email = "",
				isSync = 1,
				phone = ""
			};
			int opUserId = Convert.ToInt32(AbpSession.UserId);
			int canUp = _aiYardDbTableIssuedCard.getAudUserType(opUserId);
			if (canUp == 2 || canUp == 3)
			{
				var user2 = await UserManager.FindByIdAsync(opUserId.ToString());
				int issync = _aiYardDbTableIssuedCard.getAudPasswordType(opUserId);
				return new userInfors()
				{
					can = true,
					email = user2.EmailAddress,
					isSync = issync,
					phone = user2.PhoneNumber
				}; ;
			}
			return user;
		}

		#region 批量导入车牌
		/// <summary>
		/// 批量导入车牌
		/// </summary>
		/// <param name="files"></param>
		/// <returns></returns> 
		[AbpAuthorize(TvDigitalPayPermissions.Create)]
		public async Task<Dictionary<string, string>> BatchLoadCardNo(int isDigityPay, bool isEdit, long stationId, string billNo, string title, IFormFile files)
		{
			Dictionary<string, string> result = new Dictionary<string, string>();
			string webRootPath = _hostingEnvironment.WebRootPath;

			try
			{
				if (!(await canUpload()).can)
				{
					result.Add("retype", "-1");
					result.Add("revalue", "您无权限申请扣款流程");
					return result;
				}
				if (files == null || files.Length <= 0)
				{
					result.Add("retype", "-1");
					result.Add("revalue", "请选择需要上传的文件");
					return result;
				}
				var formFile = files;
				if (formFile.Length > 0)
				{
					string fileExt = Path.GetExtension(formFile.FileName); //文件扩展名，不含“.”
					if (fileExt != ".xls" && fileExt != ".xlsx")
					{
						result.Add("retype", "-1");
						result.Add("revalue", "请选择Excel文件格式");
						return result;
					}
					long fileSize = formFile.Length; //获得文件大小，以字节为单位
					string name = Guid.NewGuid().ToString();
					string newName = name + fileExt; //新的文件名
					var fileDire = webRootPath + string.Format("/Temp/Upload/", "");
					if (!Directory.Exists(fileDire))
					{
						Directory.CreateDirectory(fileDire);
					}

					var filePath = fileDire + newName;

					using (var stream = new FileStream(filePath, FileMode.Create))
					{
						await formFile.CopyToAsync(stream);
					}

					int opUserId = Convert.ToInt32(AbpSession.UserId);
					var user = await UserManager.FindByIdAsync(opUserId.ToString());
					string userName = user.UserName;
					string userTrueName = user.EmailAddress.Substring(0, user.EmailAddress.IndexOf('@'));
					int TenantId = Convert.ToInt32(AbpSession.TenantId);
					return await _aiYardDbTableIssuedCard.BatchLoadDigitalPay(isDigityPay, name, true, isEdit, filePath, billNo, title, stationId, TenantId, opUserId, userName, userTrueName);

					//result.Add("retype", "1");
					//result.Add("revalue", name);
					//return result;
				}
				else
				{
					result.Add("retype", "-1");
					result.Add("revalue", "上传的文件为空");
					return result;
				}
			}
			catch (Exception ex)
			{
				result.Add("retype", "-1");
				result.Add("revalue", ex.Message);
				return result;
			}
		}
		/// <summary>
		/// 批量导入车牌
		/// </summary>
		/// <param name="filename"></param>
		/// <returns></returns> 
		[AbpAuthorize(TvDigitalPayPermissions.Create)]
		public async Task<Dictionary<string, string>> BatchLoadCardNoByFileName(int isDigityPay, bool isEdit, string filename, long stationId, string billNo, string title, string psw)
		{
			Dictionary<string, string> result = new Dictionary<string, string>();
			try
			{
				if (!(await canUpload()).can)
				{
					result.Add("retype", "-1");
					result.Add("revalue", "您无权限申请扣款流程");
					return result;
				}
				string webRootPath = _hostingEnvironment.WebRootPath;
				var fileDire = webRootPath + string.Format("/Temp/Upload/", "");

				var filePath = fileDire + filename + ".xls";
				if (!File.Exists(filePath))
				{
					filePath = fileDire + filename + ".xlsx";
					if (!File.Exists(filePath))
					{
						result.Add("retype", "-1");
						result.Add("revalue", "上传的文件不存在");
						return result;
					}
				}
				int opUserId = Convert.ToInt32(AbpSession.UserId);
				var user = await UserManager.FindByIdAsync(opUserId.ToString());
				string userName = user.UserName;
				string userTrueName = user.EmailAddress.Substring(0, user.EmailAddress.IndexOf('@'));
				string phone = user.PhoneNumber;
				string spassword = MD5.MD5Encrypt(psw);
				int pswtype = _aiYardDbTableIssuedCard.getAudPasswordType(opUserId);
				string pssword = _aiYardDbTableIssuedCard.getAudPassword(opUserId);
				if (pswtype == 1)
				{
					if (pssword != spassword)
					{
						result.Add("retype", "-1");
						result.Add("revalue", "密码输入错误");
						return result;
					}
				}
				else if (pswtype == 2)
				{
					string host = _httpContext.HttpContext.Request.Host.Host.Replace("www", "pay").Replace("aiweb", "pay").Replace("webx", "pay").Replace("web.", "minipay.").Replace("yun4.", "pay.").Replace("p.", "t.");

					string Url = (host.Contains("minipay.") ? "https://" : "http://") + host + ":1888/api/v1.0/YardLogin/VerifyCmsCodeToDigityPay?phone=" + phone + "&code=" + psw;

					string vresult = _httpService.Get(Url);
					if (!vresult.Contains("验证成功"))
					{
						result.Add("retype", "-1");
						result.Add("revalue", "密码输入错误");
						return result;
					}
				}
				int TenantId = Convert.ToInt32(AbpSession.TenantId);
				Dictionary<string, string> result2 = await _aiYardDbTableIssuedCard.BatchLoadDigitalPay(isDigityPay, filename, false, isEdit, filePath, billNo, title, stationId, TenantId, opUserId, userName, userTrueName);
				string sqphone = _aiYardDbTableIssuedCard.getAudUser(2, stationId);
				AiLogger.Instance.WriteLog(sqphone + "-->" + result2.ToJson(), "扣款单上传");
				if (result2.TryGetValue("retype", out string value) && value == "1" && sqphone != "")
				{
					await sendcmsPassword(sqphone, billNo, 1);
				}
				return result2;
			}
			catch (Exception ex)
			{
				result.Add("retype", "-1");
				result.Add("revalue", "导入车牌扣款信息异常");
				return result;
			}
		}
		#endregion

		#region 审核
		/// <summary>
		/// 审核
		/// </summary>
		/// <param name="stationId"></param>
		/// <param name="billNo"></param>
		/// <returns></returns>
		public async Task<Dictionary<string, string>> CheckByBillNo(long stationId, string billNo, string checkStatus, string checkMemo, string psw)
		{
			Dictionary<string, string> result = new Dictionary<string, string>();
			try
			{
				if (!(await canCheck()).can)
				{
					result.Add("retype", "-1");
					result.Add("revalue", "您无权限签核扣款流程");
					return result;
				}

				int opUserId = Convert.ToInt32(AbpSession.UserId);
				var user = await UserManager.FindByIdAsync(opUserId.ToString());
				string userName = user.UserName;
				string userTrueName = user.EmailAddress.Substring(0, user.EmailAddress.IndexOf('@'));
				int TenantId = Convert.ToInt32(AbpSession.TenantId);
				string phone = user.PhoneNumber;
				string spassword = MD5.MD5Encrypt(psw);
				int pswtype = _aiYardDbTableIssuedCard.getAudPasswordType(opUserId);
				string pssword = _aiYardDbTableIssuedCard.getAudPassword(opUserId);
				if (pswtype == 1)
				{
					if (pssword != spassword)
					{
						result.Add("retype", "-1");
						result.Add("revalue", "密码输入错误");
						return result;
					}
				}
				else if (pswtype == 2)
				{
					string host = _httpContext.HttpContext.Request.Host.Host.Replace("www", "pay").Replace("aiweb", "pay").Replace("webx", "pay").Replace("web.", "minipay.").Replace("yun4.", "pay.").Replace("p.", "t.");

					string Url = (host.Contains("minipay.") ? "https://" : "http://") + host + ":1888/api/v1.0/YardLogin/VerifyCmsCodeToDigityPay?phone=" + phone + "&code=" + psw;

					string vresult = _httpService.Get(Url);
					if (!vresult.Contains("验证成功"))
					{
						result.Add("retype", "-1");
						result.Add("revalue", "密码输入错误");
						return result;
					}
				}
				Dictionary<string, string> result2 = await _aiYardDbTableIssuedCard.CheckDigitalPayByBillNo(stationId, billNo, checkStatus, checkMemo, opUserId, userName, userTrueName);
				string sqphone = _aiYardDbTableIssuedCard.getAudUser(1, stationId);
				AiLogger.Instance.WriteLog(sqphone + "-->" + result2.ToJson(), "扣款单审核");
				if (result2.TryGetValue("retype", out string value) && value == "1" && sqphone!="")
				{
					await sendcmsPassword(sqphone, billNo, 2);
				}
				return result2;
			}
			catch (Exception ex)
			{
				result.Add("retype", "-1");
				result.Add("revalue", "上传的文件为空");
				return result;
			}
		}
		#endregion

		#region 发送动态密码
		public async Task<string> sendcmsPassword(string phone, string billno = "", int issq = 0)
		{
			try
			{
				string host = _httpContext.HttpContext.Request.Host.Host.Replace("www", "pay").Replace("aiweb", "pay").Replace("webx", "pay").Replace("web.", "minipay.").Replace("yun4.", "pay.").Replace("p.", "t.");

				string Url = (host.Contains("minipay.") ? "https://" : "http://") + host + ":1888/api/v1.0/YardLogin/isTempPasswordToDigityPay?phone=" + phone;
				if (billno != "" && issq != 0)
				{
					Url = (host.Contains("minipay.") ? "https://" : "http://") + host + ":1888/api/v1.0/YardLogin/sendNoticeCheck?phone=" + phone + "&billno=" + billno + "&issq=" + issq;
				}
				string vresult = _httpService.Get(Url);
				return vresult.Replace('"',' ').Trim();
			}
			catch (Exception ex)
			{
				return "调用接口异常";
			}
		}
		#endregion

		#region 开始扣款
		/// <summary>
		/// 开始扣款
		/// </summary>
		/// <param name="billno"></param>
		/// <returns></returns>
		public async Task<bool> startPayDigity(string billno, long stationId)
		{
			try
			{

				var query = await _aiYardDbTableIssuedCard.GetBillInfo(stationId, billno, true);
				foreach (var item in query)
				{
					try
					{
						AiLogger.Instance.WriteLog($@"{item.plateNo}-->准备开始扣款", billno);
						string md5Key = "";
						string stationNo = "";
						string stationName = "";
						long clientId = 0;
						string clientNo = "";
						string clientName = "";

						if (!_aiYardDbTableIssuedCard.getClientInfor(billno, stationId, item.isDigityPay, ref md5Key, ref stationNo, ref stationName, ref clientId, ref clientNo, ref clientName))
						{
							_aiYardDbTableIssuedCard.updateDigityResult(billno, item.plateNo, Convert.ToInt32(item.Id ?? Convert.ToInt64("0")), item.Amout, "交易失败", "Fail", "参数错误", DateTime.Now, DateTime.Now, DateTime.Now, item.isDigityPay);
							AiLogger.Instance.WriteLog($@"{billno}-->{item.plateNo}-->获取客户端信息错误-->扣费终止", billno);
						}
						else
						{
							string host = _httpContext.HttpContext.Request.Host.Host.Replace("www", "pay").Replace("aiweb", "pay").Replace("webx", "pay").Replace("web.", "minipay.").Replace("yun4.", "pay.").Replace("p.", "t.");

							string ApiUrl = (host.Contains("minipay.") ? "https://" : "http://") + host + ":1888/";
							if (!isCCBWGPayCar(billno, item.plateNo, stationId, stationNo, stationName, clientId, clientNo, clientName, item.plateNo, item.isDigityPay, ApiUrl, md5Key))
							{
								_aiYardDbTableIssuedCard.updateDigityResult(billno, item.plateNo, Convert.ToInt32(item.Id ?? Convert.ToInt64("0")), item.Amout, "交易失败", "Fail", $@"未开通{(item.isDigityPay == 1 ? "数币无感" : "无感支付")}", DateTime.Now, DateTime.Now, DateTime.Now, item.isDigityPay);
								AiLogger.Instance.WriteLog($@"{billno}-->{item.plateNo}-->查询是否开通无感错误-->扣费终止", billno);
							}
							else
							{
								CCBWGPayBatchResponse cCBWG = new CCBWGPayBatchResponse();
								//'蓝色','黄色','白色','黑色','绿色','未知'
								int plateColor = 1;
								if (plateColor == 1) {
									plateColor = 1;
								}
								else if (plateColor == 5)
								{
									plateColor = 2;
								}
								else if (plateColor == 2)
								{
									plateColor = 3;
								}


								if (!CCBWGRun(billno, item.plateNo, stationId, stationNo, stationName, clientId, clientNo, clientName, item.plateNo, plateColor, item.isDigityPay, item.inTime ?? DateTime.Now, item.outTime ?? DateTime.Now, item.Amout, item.RecordId,
									item.plateNo + (item.outTime ?? DateTime.Now).ToString("yyyy-MM-dd HH:mm:ss") + "出场扣费", ApiUrl, md5Key, ref cCBWG))
								{
									_aiYardDbTableIssuedCard.updateDigityResult(billno, item.plateNo, Convert.ToInt32(item.Id ?? Convert.ToInt64("0")), item.Amout, "交易失败", cCBWG.result, cCBWG.message, DateTime.Now, DateTime.Now, DateTime.Now, item.isDigityPay);
									AiLogger.Instance.WriteLog($@"{billno}-->{item.plateNo}-->扣款失败-->扣费终止", billno);
								}
								else
								{
									_aiYardDbTableIssuedCard.updateDigityResult(billno, item.plateNo, Convert.ToInt32(item.Id ?? Convert.ToInt64("0")), item.Amout, "交易成功", "", "", cCBWG.requestTime, cCBWG.responseTime, cCBWG.tradeTime, item.isDigityPay);
									int opUserId = Convert.ToInt32(AbpSession.UserId);
									var user = await UserManager.FindByIdAsync(opUserId.ToString());
									string userName = user.UserName;
									string userTrueName = user.EmailAddress.Substring(0, user.EmailAddress.IndexOf('@'));
									_aiYardDbTableIssuedCard.insertOutYardpay(billno, item.plateNo, item.RecordId, item.Amout, opUserId, userTrueName, clientId, stationNo);
									AiLogger.Instance.WriteLog($@"{billno}-->{item.plateNo}-->扣款成功", billno);
								}
							}
						}
					}
					catch (Exception ex)
					{
						AiLogger.Instance.WriteLog($@"{billno}-->{item.plateNo}-->扣款异常-->" + ex.Message, billno);
					}
				}
				return true;
			}
			catch (Exception ex)
			{
				AiLogger.Instance.Error("批量扣款异常-->批量异常-->" + ex.Message);
				return false;
			}
		}
		#region 验证车辆
		/// <summary>
		/// 验证是否开通无感支付
		/// </summary>
		/// <param name="billNo"></param>
		/// <param name="plateNo"></param>
		/// <param name="Station_Id"></param>
		/// <param name="Station_No"></param>
		/// <param name="Station_Name"></param>
		/// <param name="Client_Id"></param>
		/// <param name="Client_No"></param>
		/// <param name="Client_Name"></param>
		/// <param name="AUTHNO"></param>
		/// <param name="isDigitypay"></param>
		/// <param name="_ApiUrl"></param>
		/// <param name="_MD5Key"></param>
		/// <returns></returns>
		private bool isCCBWGPayCar(string billNo, string plateNo, long Station_Id, string Station_No, string Station_Name, long Client_Id, string Client_No, string Client_Name,
										 string AUTHNO, int isDigitypay, string _ApiUrl, string _MD5Key)
		{
			try
			{

				//验证当前车辆是否开通无感支付
				CCBWGPayQueryDISIRequest request = new CCBWGPayQueryDISIRequest();
				request.Station_Id = Station_Id;
				request.Station_No = Station_No;
				request.Station_Name = Station_Name;
				request.Client_Id = Client_Id;
				request.Client_No = Client_No;
				request.Client_Name = Client_Name;
				request.AUTHNO = AUTHNO;
				request.isDigitypay = isDigitypay;
				request.CCBJHVERSION = "V1";
				string nonce = Guid.NewGuid().ToString();
				request.Nonce = nonce;
				request.Sign = MD5.MD5Encrypt((request.AUTHNO + request.isDigitypay.ToString() + request.CCBJHVERSION).ToUpper() + nonce.ToLower() + _MD5Key.ToLower()).ToLower();

				AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->" + _ApiUrl + "Api/v1.0/BarCodePay/isCCBWGPayCarBatch >>>>> " + request.ToJson(), billNo, "请求参数", plateNo);
				string response = _httpService.Post(request.ToJson(), _ApiUrl + "Api/v1.0/BarCodePay/isCCBWGPayCarBatch", 30);
				AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->" + response, billNo, "返回参数", plateNo);
				ApiReturn apireturn = Json.ToObject<ApiReturn>(response);

				if (apireturn.result == 200)
				{
					CCBWGPayQueryResponseResult check = Json.ToObject<CCBWGPayQueryResponseResult>(response);
					string sign = MD5.MD5Encrypt(Json.ToJson(check.msg).ToUpper() + apireturn.nonce.ToLower() + _MD5Key.ToLower()).ToLower();
					if (sign != apireturn.sign)
					{
						AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->验签错误-->{Json.ToJson(check)}", billNo);
						return false;
					}
					AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->验签成功-->{Json.ToJson(check)}", billNo);
					return true;

				}
				else
				{
					ApiResult result = Json.ToObject<ApiResult>(response);
					AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->查询无感状态错误-->{(result.msg ?? "错误信息为空")}", billNo);
					return false;
				}

			}
			catch (Exception ex)
			{
				AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->查询无感状态异常-->{ex.Message}", billNo);
				AiLogger.Instance.Error($@"{billNo}-->{plateNo}-->" + ex.Message);
				return false;
			}
		}
		#endregion

		#region 建行无感支付
		private bool CCBWGRun(string billNo, string plateNo, long Station_Id, string Station_No, string Station_Name, long Client_Id, string Client_No, string Client_Name,
										 string AUTHNO, int plateColor, int isDigitypay, DateTime inTime, DateTime outTime, decimal Amount, int IN_ID, string Pay_subject, string _ApiUrl, string _MD5Key, ref CCBWGPayBatchResponse cCBWGPay)
		{
			try
			{
				//准备扫码支付
				YardPayCCBDisiRequest request = new YardPayCCBDisiRequest();
				request.Station_Id = Station_Id;
				request.Station_No = Station_No;
				request.Station_Name = Station_Name;
				request.Client_Id = Client_Id;
				request.Client_No = Client_No;
				request.Client_Name = Client_Name;
				request.yardPay = new YardPayCCBDisiModels();
				request.yardPay.Amount = (int)Math.Truncate(Amount * 100);
				request.yardPay.ApiVersion = "V1.0";
				request.yardPay.AUTHNO = AUTHNO;
				request.yardPay.PlateColor = plateColor;
				request.yardPay.goods_tag = "停车费";
				request.yardPay.paysource = Paysource.CC;
				request.yardPay.Pay_subject = Pay_subject;
				request.yardPay.RecordId = IN_ID;
				request.yardPay.isDigitypay = isDigitypay;
				request.yardPay.InTime = inTime.ToString("yyyyMMddHHmmss");
				request.yardPay.OutTime = outTime.ToString("yyyyMMddHHmmss");
				TimeSpan time = outTime - inTime;
				request.yardPay.StopTime = Convert.ToInt32(Math.Truncate(time.TotalMinutes));

				var dic = JsonConvert.DeserializeObject<SortedDictionary<string, object>>(Json.ToJson(request.yardPay));
				SortedDictionary<string, object> keyValues = new SortedDictionary<string, object>(dic);
				keyValues.OrderBy(m => m.Key);//升序 把Key换成Value 就是对Value进行排序
											  //keyValues.OrderByDescending(m => m.Key);//降序

				string json = JsonConvert.SerializeObject(keyValues);

				string nonce = Guid.NewGuid().ToString();
				request.Nonce = nonce;
				request.Sign = MD5.MD5Encrypt(json.ToUpper() + nonce.ToLower() + _MD5Key.ToLower()).ToLower();

				AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->" + _ApiUrl + "Api/v1.0/BarCodePay/codeCCBWGPayBatch >>>>> " + request.ToJson(), billNo, "请求参数", plateNo);
				string response = _httpService.Post(request.ToJson(), _ApiUrl + "Api/v1.0/BarCodePay/codeCCBWGPayBatch", 30);
				AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->" + response, billNo, "返回参数", plateNo);
				ApiReturn apireturn = Json.ToObject<ApiReturn>(response);

				if (apireturn.result == 200 || apireturn.result == 201)
				{
					ApiObject result = Json.ToObject<ApiObject>(response);
					CCBWGPayBatchResponse check = Json.ToObject<CCBWGPayBatchResponse>(result.msg.ToJson());
					cCBWGPay = check;
					var dic2 = JsonConvert.DeserializeObject<SortedDictionary<string, object>>(Json.ToJson(check));
					SortedDictionary<string, object> keyValues2 = new SortedDictionary<string, object>(dic2);
					keyValues2.OrderBy(m => m.Key);//升序 把Key换成Value 就是对Value进行排序
												   //keyValues.OrderByDescending(m => m.Key);//降序

					string json2 = JsonConvert.SerializeObject(keyValues2);
					AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->签名原始串-->{json2}", billNo);
					string sign = MD5.MD5Encrypt(json2.ToUpper() + apireturn.nonce.ToLower() + _MD5Key.ToLower()).ToLower();
					if (sign != apireturn.sign)
					{
						AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->支付验签错误-->{Json.ToJson(check)}", billNo);
						return false;
					}
					AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->支付验签成功-->{Json.ToJson(check)}", billNo);
					if (apireturn.result == 200)
					{
						AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->支付成功-->{Json.ToJson(check)}", billNo);
						return true;
					}
					AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->支付失败-->{Json.ToJson(check)}", billNo);
					return false;

				}
				else
				{
					ApiResult result = Json.ToObject<ApiResult>(response);
					cCBWGPay = new CCBWGPayBatchResponse()
					{
						message = result.msg ?? "错误信息为空",
						result = "Fail"
					};
					AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->支付错误-->{(result.msg ?? "错误信息为空")}", billNo);
					return false;
				}
			}
			catch (Exception ex)
			{
				AiLogger.Instance.WriteLog($@"{billNo}-->{plateNo}-->支付异常-->{ex.Message}", billNo);
				AiLogger.Instance.Error($@"{billNo}-->{plateNo}-->" + ex.Message);
				cCBWGPay = new CCBWGPayBatchResponse()
				{
					message = "调用支付接口异常",
					result = "Fail"
				};
				return false;
			}
		}
		#endregion
		#endregion

		#region 转换无感支付
		/// <summary>
		/// 转换无感支付
		/// </summary>
		/// <param name="stationId"></param>
		/// <param name="billNo"></param>
		/// <returns></returns>
		public async Task<bool> ChangeBillWG(long stationId, string billNo)
		{
			int opUserId = Convert.ToInt32(AbpSession.UserId);
			var user = await UserManager.FindByIdAsync(opUserId.ToString());
			string userName = user.UserName;
			string userTrueName = user.EmailAddress.Substring(0, user.EmailAddress.IndexOf('@'));
			return await _aiYardDbTableIssuedCard.ChangeBillWG(stationId, billNo, opUserId, userName, userTrueName);
		}
		#endregion

		///// <summary>
		///// 导出TvDigitalPay为excel表,等待开发。
		///// </summary>
		///// <returns></returns>
		//public async Task<FileDto> GetToExcel()
		//{
		//	var users = await UserManager.Users.ToListAsync();
		//	var userListDtos = ObjectMapper.Map<List<UserListDto>>(users);
		//	await FillRoleNames(userListDtos);
		//	return _userListExcelExporter.ExportToFile(userListDtos);
		//}

	}
    public class CCBWGPayBatchResponse
	{
		public string result { get; set; }
		public string message { get; set; }
		public DateTime requestTime { get; set; }
		public DateTime responseTime { get; set; }
		public DateTime tradeTime { get; set; }
		public string TRACEID { get; set; }
		public string OUT_TRADE_NO { get; set; }
	}
	public class queryfilterText
	{
		public int Checked {get;set;}
		public string bTime { get; set; }
		public string eTime { get; set; }
	}
	public class userInfors
	{
		public string phone { get; set; }
		public string email { get; set; }
		public int isSync { get; set; }
		public bool can { get; set; }
	}
	public class CCBWGPayQueryDISIRequest
	{
		/// <summary>
		/// 场所编号
		/// </summary>
		public long Station_Id { get; set; }
		/// <summary>
		/// 场所代码
		/// </summary>
		public string Station_No { get; set; }
		/// <summary>
		/// 场所名称
		/// </summary>
		public string Station_Name { get; set; }
		/// <summary>
		/// 客户端编号
		/// </summary>
		public long Client_Id { get; set; }
		/// <summary>
		/// 客户端代码
		/// </summary>
		public string Client_No { get; set; }
		/// <summary>
		/// 客户端名称
		/// </summary>
		public string Client_Name { get; set; }
		/// <summary>
		/// 已登录验证信息
		/// </summary>
		public string AUTHNO { get; set; }
		/// <summary>
		/// 是否数币查询
		/// </summary>
		public int isDigitypay { get; set; }
		/// <summary>
		/// 建行接口版本
		/// </summary>
		public string CCBJHVERSION { get; set; }
		/// <summary>
		/// 随机串
		/// </summary>
		public string Nonce { get; set; }
		/// <summary>
		/// 签名
		/// </summary>
		public string Sign { get; set; }
	}
	public class CCBWGPayQueryResponseResult
	{
		/// <summary>
		/// 返回结果 200 成功 其他失败
		/// </summary>
		public int result { get; set; }
		/// <summary>
		/// 返回信息
		/// </summary>
		public CCBWGPayQueryResponse msg { get; set; }
		/// <summary>
		/// 随机串
		/// </summary>
		public string nonce { get; set; }
		/// <summary>
		/// 签名串
		/// </summary>
		public string sign { get; set; }
	}
	public class CCBWGPayQueryResponse
	{
		public string message { get; set; }
	}
	public class YardPayCCBDisiRequest
	{ /// <summary>
	  /// 场所编号
	  /// </summary>
		public long Station_Id { get; set; }
		/// <summary>
		/// 场所代码
		/// </summary>
		public string Station_No { get; set; }
		/// <summary>
		/// 场所名称
		/// </summary>
		public string Station_Name { get; set; }
		/// <summary>
		/// 客户端编号
		/// </summary>
		public long Client_Id { get; set; }
		/// <summary>
		/// 客户端代码
		/// </summary>
		public string Client_No { get; set; }
		/// <summary>
		/// 客户端名称
		/// </summary>
		public string Client_Name { get; set; }
		/// <summary>
		/// 无关支付请求参数
		/// </summary>
		public YardPayCCBDisiModels yardPay { get; set; }
		/// <summary>
		/// 随机串
		/// </summary>
		public string Nonce { get; set; }
		/// <summary>
		/// 签名
		/// </summary>
		public string Sign { get; set; }
	}
	public class YardPayCCBDisiModels
	{
		/// <summary>
		/// 来源
		/// </summary>
		public Paysource paysource { get; set; }
		/// <summary>
		/// 原始记录编号
		/// </summary>
		public int RecordId { get; set; }
		/// <summary>
		/// 支付金额 *100后的
		/// </summary>
		public int Amount { get; set; }
		/// <summary>
		/// 车牌号码
		/// </summary>
		public string AUTHNO { get; set; }
		/// <summary>
		/// 车牌颜色
		/// </summary>
		public int PlateColor { get; set; }
		/// <summary>
		/// 进场时间
		/// </summary>
		public string InTime { get; set; }
		/// <summary>
		/// 出场时间
		/// </summary>
		public string OutTime { get; set; }
		/// <summary>
		/// 停车时间
		/// </summary>
		public int StopTime { get; set; }
		/// <summary>
		/// 无感支付接口版本
		/// </summary>
		public string goods_tag { get; set; }
		/// <summary>
		/// 支付说明
		/// </summary>
		public string Pay_subject { get; set; }
		/// <summary>
		/// 接口版本
		/// </summary>
		public string ApiVersion { get; set; }
		/// <summary>
		/// 数币扣款
		/// </summary>
		public int isDigitypay { get; set; }
	}
	public class PaySuccessResultV2
	{
		public int trade_id { get; set; }
		public string trade_no { get; set; }
		public int recordid { get; set; }
		public int total_amount { get; set; }
		public string gmt_create { get; set; }
		public string out_trade_no { get; set; }
		public string trade_type { get; set; }
		public string trade_code { get; set; }
		public string FreeNo { get; set; }
		public string FreeType { get; set; }
		public string FreeName { get; set; }
		public int FreeCount { get; set; }
	}
}


